import os
import re

import scrapy
from  scrapy import  Selector,Request


from ..items import XiaoshuoItem

from ..settings import memory_dict




class XiaoshuoSpider(scrapy.Spider):
    name = 'XIAOSHUO'
    allowed_domains = ['www.shuben.co']
    start_urls = ['http://www.shuben.co/txt/84303.html']

    # 存储所有章节数据的列表
    all_chapters = []

    # 记录已爬取的章节数量
    chapter_count = 0

    # 总章节数量
    total_chapters = 0

    # def __int__(self):
    #     pass

    def __init__(self, *args, **kwargs):
        super(XiaoshuoSpider, self).__init__(*args, **kwargs)
        # 删除旧文件，避免追加到旧内容
        if os.path.exists('完美世界.txt'):
            os.remove('完美世界.txt')

    def extract_chapter_number(self, title):
        """从章节标题中提取章节编号，支持中文数字"""
        # 尝试匹配"第X章"或"第X节"等格式（阿拉伯数字）
        match = re.search(r'第(\d+)[章节]', title)
        if match:
            return int(match.group(1))

        # 尝试匹配"第[中文数字]章"格式
        match = re.search(r'第(.*?)[章节]', title)
        if match:
            chinese_num = match.group(1)
            try:
                return self.chinese_to_arabic(chinese_num)
            except:
                self.logger.warning(f"无法转换中文数字: {chinese_num}")

        # 尝试匹配纯数字
        match = re.search(r'(\d+)', title)
        if match:
            return int(match.group(1))

        # 如果无法提取编号，返回标题的哈希值作为替代
        return hash(title)

    def chinese_to_arabic(self, chinese_num):
        """将中文数字转换为阿拉伯数字"""
        # 记录原始输入，用于调试
        original_input = chinese_num

        # 中文数字到阿拉伯数字的映射
        cn_num = {
            '零': 0, '一': 1, '二': 2, '两': 2, '三': 3, '四': 4,
            '五': 5, '六': 6, '七': 7, '八': 8, '九': 9
        }

        # 中文单位到值的映射
        cn_unit = {
            '十': 10, '百': 100, '千': 1000,
            '万': 10000, '亿': 100000000
        }

        # 去除"零"简化处理
        chinese_num = chinese_num.replace('零', '')

        # 特殊情况处理
        if chinese_num == '十':
            return 10
        if chinese_num.startswith('十'):
            chinese_num = '一' + chinese_num

        # 使用更简单的方法
        result = 0
        temp_result = 0

        # 处理亿级别
        parts = chinese_num.split('亿')
        if len(parts) > 1:
            if parts[0]:
                temp_result = self.chinese_to_arabic_simple(parts[0])
                result = temp_result * 100000000
            if parts[1]:
                result += self.chinese_to_arabic_simple(parts[1])
            return result

        # 处理万级别
        parts = chinese_num.split('万')
        if len(parts) > 1:
            if parts[0]:
                temp_result = self.chinese_to_arabic_simple(parts[0])
                result = temp_result * 10000
            if parts[1]:
                result += self.chinese_to_arabic_simple(parts[1])
            return result

        # 处理千百十个位
        return self.chinese_to_arabic_simple(chinese_num)

    def chinese_to_arabic_simple(self, chinese_num):
        """处理千百十个位的中文数字"""
        cn_num = {
            '零': 0, '一': 1, '二': 2, '两': 2, '三': 3, '四': 4,
            '五': 5, '六': 6, '七': 7, '八': 8, '九': 9
        }

        cn_unit = {
            '十': 10, '百': 100, '千': 1000
        }

        result = 0
        i = 0

        # 处理千位
        if '千' in chinese_num:
            idx = chinese_num.find('千')
            if idx > 0:
                result += cn_num[chinese_num[idx - 1]] * 1000
            else:
                result += 1000  # 省略了"一"
            i = idx + 1

        # 处理百位
        if i < len(chinese_num) and '百' in chinese_num[i:]:
            idx = chinese_num.find('百', i)
            if idx > i:
                result += cn_num[chinese_num[idx - 1]] * 100
            else:
                result += 100  # 省略了"一"
            i = idx + 1

        # 处理十位
        if i < len(chinese_num) and '十' in chinese_num[i:]:
            idx = chinese_num.find('十', i)
            if idx > i:
                result += cn_num[chinese_num[idx - 1]] * 10
            else:
                result += 10  # 省略了"一"
            i = idx + 1

        # 处理个位
        if i < len(chinese_num) and chinese_num[i:] in cn_num:
            result += cn_num[chinese_num[i:]]
        elif i < len(chinese_num) and len(chinese_num[i:]) == 1 and chinese_num[i:] in cn_num:
            result += cn_num[chinese_num[i:]]

        return result

    def parse(self, response):
        sel=Selector(response)
        a_tags=sel.xpath('//*[@id="list"]/dl/a[@rel="chapter"]')
        #print(a_tags)

        # 记录总章节数
        self.total_chapters = len(a_tags)
        print('总章节数:' + str(self.total_chapters))
        self.logger.info(f"总共发现 {self.total_chapters} 个章节")
        # 创建一个列表存储章节信息
        chapters = []
        for a in a_tags :
            # 创建item实例而不是使用类变量
            item = XiaoshuoItem()
            item['title'] = a.xpath('./@title').extract()[0]
            item['href'] = response.urljoin(a.xpath('./@href').extract()[0])
            # print(item['title'], item['href'])
            # 提取章节编号用于排序
            chapter_num = self.extract_chapter_number(item['title'])
            item['chapters']=chapter_num
            print(chapter_num)
            chapters.append({
                'item': item,
                'chapter_num': chapter_num
            })
            # print(XiaoshuoItem.title,XiaoshuoItem.href)
            yield Request(url=item['href'],callback=self.parseContent,meta={'item':item})


    def parseContent(self,response):
        item=response.meta['item']
        print('11111111111111111111111111111111111111111111111'+item['title'])
        sel = Selector(response)
        title1=sel.xpath('//*[@id="read-block"]/h1/text()').extract()[0]
        contents=sel.xpath('//*[@id="content"]/p')
        print(title1+'\r\n')
        # 收集章节内容
        # content_text = title1 + '\r\n'
        item['content']=title1+'\r\n'
        for i in contents:
            c=i.xpath('./text()').extract()[0]
            print(c)
            item['content'] += c + '\r\n'

        # 查找下一页按钮
        next_page_button = response.xpath('//*[@id="bottom-jump-page"]/span[3]/a')
        next_page_url = next_page_button.xpath('./@href').extract_first()
        next_page_text=next_page_button.xpath('./text()').extract_first()
        # 如果存在下一页且不是“下一章”按钮，递归请求下一页
        #把章节编号，做为key，章节内容做value，存入字典
        memory_dict[item['chapters']]=item['content']
        if next_page_url and '下一章' not in next_page_text:
            yield scrapy.Request(response.urljoin(next_page_url), callback=self.parseContent_nextpage,meta={'item':item})

    def parseContent_nextpage(self, response):
        item = response.meta['item']
        sel = Selector(response)
        title1 = sel.xpath('//*[@id="read-block"]/h1/text()').extract()[0]
        contents = sel.xpath('//*[@id="content"]/p')
        print(title1 + '\r\n')
        for i in contents:
            c = i.xpath('./text()').extract()[0]
            print(c)
            item['content'] += c + '\r\n'

        # 查找下一页按钮
        next_page_button = response.xpath('//*[@id="bottom-jump-page"]/span[3]/a')
        next_page_url = next_page_button.xpath('./@href').extract_first()
        next_page_text = next_page_button.xpath('./text()').extract_first()
        # 如果存在下一页且不是“下一章”按钮，递归请求下一页
        # 把章节编号，做为key，章节内容做value，存入字典
        memory_dict[item['chapters']] = item['content']
        if next_page_url and next_page_text=='下一页':
            yield scrapy.Request(response.urljoin(next_page_url), callback=self.parseContent_nextpage, meta={'item': item})


        # with open('完美世界.txt', "a", encoding='utf-8') as f:  # 设置文件对象
        #
        #     f.write(title1+'\r\n')
        #     for i in contents:
        #         c=i.xpath('./text()').extract()[0]
        #         print(c)
        #         f.write(c+'\r\n')  # 可以是随便对文件的操作


    def close(self, reason):
        print(memory_dict.keys())
        n=len(memory_dict)
        print(n)
        with open('D://惊鸿.txt', 'a+', encoding='utf-8') as fp:
            for i in range(n):  # 自己制定要保存前多少章咯
                try:
                    fp.write(str(i) + '\n' + memory_dict[i])
                except:
                    pass






